#include <string>
#include <unordered_map>

using namespace std;

class User
{
public:
    User(const string& ip,const uint16_t& port)
        :ip_(ip),port_(port)
    {}
    ~User(){}
    string ip(){return ip_;}
    uint16_t port(){return port_;}
private:
    string ip_;
    uint16_t port_;
};

class OnlineUser
{
public:
    OnlineUser(){}
    void addUser(const string& ip,const uint16_t& port)
    {
        string id=ip+"-"+to_string(port);
        users.insert(make_pair(id,User(ip,port)));
    }
    void delUser(const string& ip,const uint16_t& port)
    {
        string id=ip+"-"+to_string(port);
        users.erase(id);
    }

    bool isOnline(const string& ip,const uint16_t& port)
    {
        string id=ip+"-"+to_string(port);
        return users.find(id) != users.end();
    }
    void boardcastMessage(int sockfd,const string& ip,const uint16_t& port,const string& message)
    {
        for(auto& user:users)
        {
            struct sockaddr_in client;
            bzero(&client,sizeof(client));
            client.sin_family=AF_INET;
            client.sin_addr.s_addr=inet_addr(user.second.ip().c_str());
            client.sin_port=htons(user.second.port());
            string s=ip+"-"+to_string(port)+" # ";
            s+=message;
            sendto(sockfd,s.c_str(),s.size(),0,(struct sockaddr *)&client,sizeof(client));

        }
    }
    ~OnlineUser(){}
private:
    unordered_map<string,User> users;
};